package ThreadBaseTest;

/**
 * 生产者与消费者
 * Created by yexuan on 2018/3/7.
 */

/**
 从单线程变成多线程，想着本来程序里的判断语句是  if，而if只判断一次，
 想着换成while(flag),结果会出现生产一个商品，消费两个，或者生产两个消费一个的情况，
 后来才发现把程序中的 notify()全部变成notifyAll()就解决了这个问题。
 */

class Resource{
    private String name;
    private int no;
    private boolean flag = false;

    public synchronized void set(String name) {
        while (flag)
            try {
                wait();
            }catch (Exception e){}
        
        this.name = name +"---"+no++;
        System.out.println(Thread.currentThread().getName()+"..生产了...."+this.name);
        this.flag = true;
        notifyAll();
    }

    public synchronized void out(){
        while(!flag)
            try {
                wait();
            }catch (Exception e){}
            
        System.out.println(Thread.currentThread().getName()+"..消费了......"+this.name);
        flag = false;
        notifyAll();
    }
}

class Producer implements Runnable{
    private Resource resource;

    public Producer(Resource resource) {
        this.resource = resource;
    }
    @Override
    public void run() {
        while (true){
            resource.set("商品");
        }
    }
}

class Customer implements Runnable{

    private Resource resource;

    public Customer(Resource resource) {
        this.resource = resource;
    }
    @Override
    public void run() {
        while (true) {
            resource.out();
        }
    }
}
public class ProducerCustomerDemo {
    public static void main(String[] args) {
        Resource r = new Resource();

        Producer p = new Producer(r);
        Customer c = new Customer(r);

        Thread t1 = new Thread(p);
        Thread t2 = new Thread(p);
        Thread t3 = new Thread(c);
        Thread t4 = new Thread(c);

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
